package com.ifacebox.arcsoft.face;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * @author znn
 */
@RestController
public class CommandController {
    private static final Logger logger = LoggerFactory.getLogger(CommandController.class);

    @GetMapping("/cmd")
    public ResponseEntity<StreamingResponseBody> cmd(String[] cmd, String dir) throws IOException {
        if (logger.isInfoEnabled()) {
            logger.info("Command:{}\t{}", Arrays.toString(cmd), dir);
        }
        Process process = new ProcessBuilder()
                .directory(dir != null && new File(dir).isDirectory() ? new File(dir) : null)
                .command(cmd).redirectErrorStream(true).start();
        return ResponseEntity.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(os -> {
            try {
                copy(process.getInputStream(), os);
            } finally {
                process.destroy();
            }
        });
    }


    @GetMapping("/exec")
    public ResponseEntity<StreamingResponseBody> exec(String[] cmd, String[] env, String dir) throws IOException {
        if (logger.isInfoEnabled()) {
            logger.info("Command:{}\t{}\t{}", Arrays.toString(cmd), Arrays.toString(env), dir);
        }
        Process process = Runtime.getRuntime().exec(cmd, env, dir != null && new File(dir).isDirectory() ? new File(dir) : null);
        return ResponseEntity.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(os -> {
            try {
                copy(process.getInputStream(), os);
                copy(process.getErrorStream(), os);
            } finally {
                process.destroy();
            }
        });
    }

    static void copy(InputStream in, OutputStream out) throws IOException {
        Charset charset = System.getProperty("os.name").toLowerCase().contains("win")
                ? Charset.forName("GBK") : Charset.defaultCharset();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset))) {
            String line;
            while ((line = reader.readLine()) != null) {
                StreamUtils.copy(line + "\n", charset, out);
            }
        }
    }
}
